From: Ivan Molodetskikh Date: Mon, 11 Oct 2021 05:47:21 +0000 (+0300) Subject: screenshot-ui: Add area and screen recording X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~530^2^2~168 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=003eb4c4e014b31bd5d55f7910b2a821a5c4ee38;p=gnome-shell.git screenshot-ui: Add area and screen recording It works by passing the selected area to org.gnome.Shell.ScreencastArea. Part-of: --- diff --git a/js/ui/screenshot.js b/js/ui/screenshot.js index 741737623..54c56f846 100644 --- a/js/ui/screenshot.js +++ b/js/ui/screenshot.js @@ -27,6 +27,9 @@ const { DBusSenderChecker } = imports.misc.util; const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot'); +const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast'); +const ScreencastProxy = Gio.DBusProxy.makeProxyWrapper(ScreencastIface); + var IconLabelButton = GObject.registerClass( class IconLabelButton extends St.Button { _init(iconName, label, params) { @@ -1332,6 +1335,9 @@ var ScreenshotUI = GObject.registerClass({ if (this._openingCoroutineInProgress) return; + if (this._screencastInProgress) + return; + if (!this.visible) { // Screenshot UI is opening from completely closed state // (rather than opening back from in process of closing). @@ -1601,7 +1607,7 @@ var ScreenshotUI = GObject.registerClass({ } } - _getSelectedGeometry() { + _getSelectedGeometry(rescale) { let x, y, w, h; if (this._selectionButton.checked) { @@ -1617,21 +1623,24 @@ var ScreenshotUI = GObject.registerClass({ h = monitor.height; } - x *= this._scale; - y *= this._scale; - w *= this._scale; - h *= this._scale; + if (rescale) { + x *= this._scale; + y *= this._scale; + w *= this._scale; + h *= this._scale; + } return [x, y, w, h]; } _onCaptureButtonClicked() { - if (this._shotButton.checked) + if (this._shotButton.checked) { this._saveScreenshot(); - - // TODO: screencasting. - - this.close(); + this.close(); + } else { + // Screencast closes the UI on its own. + this._startScreencast(); + } } _storeScreenshot(bytes, pixbuf) { @@ -1773,7 +1782,7 @@ var ScreenshotUI = GObject.registerClass({ const texture = content.get_texture(); const stream = Gio.MemoryOutputStream.new_resizable(); - const [x, y, w, h] = this._getSelectedGeometry(); + const [x, y, w, h] = this._getSelectedGeometry(true); let cursorTexture = this._cursor.content?.get_texture(); if (!this._cursor.visible) @@ -1830,6 +1839,71 @@ var ScreenshotUI = GObject.registerClass({ } } + _startScreencast() { + if (this._windowButton.checked) + return; // TODO + + const [x, y, w, h] = this._getSelectedGeometry(false); + const drawCursor = this._cursor.visible; + + // Close instantly so the fade-out doesn't get recorded. + this.close(true); + + // This is a bit awkward because creating a proxy synchronously hangs Shell. + const doStartScreencast = () => { + let method = + this._screencastProxy.ScreencastRemote.bind(this._screencastProxy); + if (w !== -1) { + method = this._screencastProxy.ScreencastAreaRemote.bind( + this._screencastProxy, x, y, w, h); + } + + method( + /* Translators: this is a filename used for screencast + * recording, where "%d" and "%t" date and time, e.g. + * "Screencast from 07-17-2013 10:00:46 PM.webm" */ + /* xgettext:no-c-format */ + _('Screencast from %d %t.webm'), + { 'draw-cursor': new GLib.Variant('b', drawCursor) }, + ([success, _filename], error) => { + if (error !== null) { + this._setScreencastInProgress(false); + log('Error starting screencast: %s'.format(error.message)); + return; + } + + if (!success) { + this._setScreencastInProgress(false); + log('Error starting screencast'); + } + } + ); + }; + + // Set this before calling the method as the screen recording indicator + // will check it before the success callback fires. + this._setScreencastInProgress(true); + + if (this._screencastProxy) { + doStartScreencast(); + } else { + new ScreencastProxy( + Gio.DBus.session, + 'org.gnome.Shell.Screencast', + '/org/gnome/Shell/Screencast', + (object, error) => { + if (error !== null) { + log('Error connecting to the screencast service'); + return; + } + + this._screencastProxy = object; + doStartScreencast(); + } + ); + } + } + stopScreencast() { if (!this._screencastInProgress) return; @@ -1837,6 +1911,16 @@ var ScreenshotUI = GObject.registerClass({ // Set this before calling the method as the screen recording indicator // will check it before the success callback fires. this._setScreencastInProgress(false); + + this._screencastProxy.StopScreencastRemote((success, error) => { + if (error !== null) { + log('Error stopping screencast: %s'.format(error.message)); + return; + } + + if (!success) + log('Error stopping screencast'); + }); } get screencast_in_progress() {